package com.one.blocks.rbac.manager;

import com.alicp.jetcache.anno.Cached;
import com.one.blocks.mvc.manager.AbstractBatchManager;
import com.one.blocks.rbac.constant.RbacConstant.OrgCache;
import com.one.blocks.rbac.domain.SysOrg;
import com.one.blocks.rbac.domain.SysRole;
import com.one.blocks.rbac.enums.CacheEventEnum;
import com.one.blocks.rbac.enums.RoleTypeEnum;
import com.one.blocks.rbac.listener.CacheEventPublisher;
import com.one.blocks.rbac.mapper.SysOrgMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author <a href="mailto:idler41@163.con">idler41</a> created on 2022-05-01 10:06:14
 */
@Slf4j
@Service
public class SysOrgManager extends AbstractBatchManager<SysOrgMapper, SysOrg> {

    @Autowired
    private SysRoleOrgManager sysRoleOrgManager;

    @Autowired
    public SysOrgManager(SysOrgMapper mapper) {
        super(mapper);
    }

    @CacheEventPublisher({CacheEventEnum.CLEAR_ORG_ROLE})
//    @CacheInvalidate(area = OrgCache.AREA, name = OrgCache.TREE)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean insert(SysOrg entity) {
        return super.insert(entity);
    }

    @CacheEventPublisher({CacheEventEnum.CLEAR_ORG_ROLE})
//    @CacheInvalidate(area = OrgCache.AREA, name = OrgCache.TREE)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean delete(Serializable id) {
        return super.delete(id);
    }

    @CacheEventPublisher({CacheEventEnum.CLEAR_ORG_ROLE})
//    @CacheInvalidate(area = OrgCache.AREA, name = OrgCache.TREE)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateById(SysOrg entity) {
        return super.updateById(entity);
    }

    @CacheEventPublisher({CacheEventEnum.CLEAR_ORG_ROLE})
//    @CacheInvalidate(area = OrgCache.AREA, name = OrgCache.TREE)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateSelectiveById(SysOrg entity) {
        return super.updateSelectiveById(entity);
    }

    @CacheEventPublisher({CacheEventEnum.CLEAR_ORG_ROLE})
//    @CacheInvalidate(area = OrgCache.AREA, name = OrgCache.TREE)
    @Override
    public int deleteByIdList(Collection<? extends Serializable> idList) {
        return super.deleteByIdList(idList);
    }

    public List<SysOrg> selectByRole(SysRole sysRole) {
        // 平台管理员 => 指定租户查询该租户所有组织
        if (RoleTypeEnum.COMMON.match(sysRole.getType())) {
            return selectByRoleId(sysRole.getId());
        } else if (RoleTypeEnum.PLATFORM_ADMIN.match(sysRole.getType())) {
            // 平台管理员拥有最高权限
            return selectAll();
        }

        // 错误的角色类型
        log.warn("错误的角色类型!roleId={},type={}", sysRole.getId(), sysRole.getType());
        return Collections.emptyList();
    }

    private List<SysOrg> selectAll() {
        return mapper.selectAll();
    }

    @Cached(area = OrgCache.AREA, name = OrgCache.ROLE_ID, key = "#roleId")
    public List<SysOrg> selectByRoleId(Integer roleId) {
        List<Integer> orgIdList = sysRoleOrgManager.selectOrgByRoleId(roleId);
        if (CollectionUtils.isEmpty(orgIdList)) {
            return Collections.emptyList();
        }
        List<SysOrg> result = new ArrayList<>(orgIdList.size());
        for (Integer id : orgIdList) {
            result.add(get(id));
        }
        return result;
    }
}